﻿#pragma once

#include <qobject.h>
#include <qtimer.h>

template <class State, class StateOwner, class ResultHandler>
class StateChecker :public QObject
{
private:
	State state;//需要达到的状态
	StateOwner* stateOwner = Q_NULLPTR;//拥有状态位的对象
	State(StateOwner::*stateGetter)() = Q_NULLPTR;//获取状态的函数
	ResultHandler* resultHandler = Q_NULLPTR;//结果处理者
	void(ResultHandler::*handleStateReached)() = Q_NULLPTR;//状态达到时的处理函数
	void(ResultHandler::*handleStateCheckTimeout)() = Q_NULLPTR;//状态检查超时时的处理函数

	QTimer timer_stateCheck;
	QTimer timer_timeLimit;
	int timeInterval_checkState = 300;//检查状态时间间隔
	int timeInterval_timeLimit = 0;//最大检查时间
private:
	explicit StateChecker(QObject* parent = Q_NULLPTR) :QObject(parent)
	{
	}
	virtual ~StateChecker()
	{
	}
public:
	static bool checkState(
		State state,
		StateOwner* stateOwner,
		State(StateOwner::* stateGetter)(),
		ResultHandler* resultHandler,
		void(ResultHandler::*handleStateReached)(),
		void(ResultHandler::*handleStateCheckTimeout)(),
		int timeLimit)
	{
		if (Q_NULLPTR == stateOwner || 
			Q_NULLPTR == stateGetter || 
			Q_NULLPTR == resultHandler || 
			Q_NULLPTR== handleStateReached ||
			Q_NULLPTR == handleStateCheckTimeout ||
			timeLimit <= 0 )//必须严格保证每个参数都是可用的
		{
			return false;
		}
		StateChecker<State, StateOwner, ResultHandler>* stateChecker = new StateChecker<State, StateOwner, ResultHandler>();
		stateChecker->state= state;
		stateChecker->stateOwner = stateOwner;
		stateChecker->stateGetter = stateGetter;
		stateChecker->resultHandler = resultHandler;
		stateChecker->handleStateReached = handleStateReached;
		stateChecker->handleStateCheckTimeout = handleStateCheckTimeout;
		stateChecker->timeInterval_timeLimit = timeLimit;
		connect(&stateChecker->timer_stateCheck, &QTimer::timeout, [=]() {stateChecker->timer_stateCheck_timeout(); });
		connect(&stateChecker->timer_timeLimit, &QTimer::timeout, [=]() {stateChecker->timer_timeLimit_timeout(); });
		stateChecker->timer_stateCheck.start(stateChecker->timeInterval_checkState);
		stateChecker->timer_timeLimit.start(stateChecker->timeInterval_timeLimit);
		return true;
	}
private:
	void timer_stateCheck_timeout()
	{
		if ((stateOwner->*stateGetter)() == state)
		{//如果状态位达到目标状态，则停止计时器，并执行状态到达函数
			timer_timeLimit.stop();
			timer_stateCheck.stop();
			(resultHandler->*handleStateReached)();
			delete this;//删除自己
		}
	}
	void timer_timeLimit_timeout()
	{//如果超过最大限制时间后仍没有达到目标状态，则停止计时器，并执行超时函数
		timer_stateCheck.stop();
		timer_timeLimit.stop();
		(resultHandler->*handleStateCheckTimeout)();
		delete this;//删除自己
	}
};
